using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Microsoft.Win32;

namespace FROG
{
    public partial class ConnectionDialog : Form
    {
        public ConnectionDialog()
        {
            InitializeComponent();
            cmbDSN.DataSource = EnumDsn();
            dbBindingSource.DataSource = App.Config;
            lstDatabases.SelectedIndex = -1;
        }

        private List<string> EnumDsn()
        {
            List<string> list = new List<string>();
            list.AddRange(EnumDsn(Registry.CurrentUser));
            list.AddRange(EnumDsn(Registry.LocalMachine));
            return list;
        }

        private IEnumerable<string> EnumDsn(RegistryKey rootKey)
        {
            RegistryKey regKey = rootKey.OpenSubKey(@"Software\ODBC\ODBC.INI\ODBC Data Sources");
            if (regKey != null)
            {
                foreach (string name in regKey.GetValueNames())
                {
                    string value = regKey.GetValue(name, "").ToString();
                    if (value.StartsWith("Oracle Lite"))
                    {
                        yield return name;
                    }
                }
            }
        }

        private bool _dbModified = false;
        private Database _currentDb = null;
        private int _currentDbIndex = -1;
        private bool _listModified = false;

        public Database SelectedDatabase
        {
            get { return _currentDb; }
            set { lstDatabases.SelectedIndex = App.Config.Databases.IndexOf(_currentDb); }
        }

        private void lstDatabases_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!ConfirmChange())
            {
                lstDatabases.SelectedIndex = _currentDbIndex;
                return;
            }

            Database db = lstDatabases.SelectedItem as Database;
            _currentDb = db;
            _currentDbIndex = lstDatabases.SelectedIndex;

            if (db == null)
            {
                txtDbName.Clear();
                cmbDSN.SelectedIndex = -1;
                txtUsername.Clear();
                txtPassword.Clear();
                chkAutoCommit.Checked = false;
                splListDetails.Panel2.Visible = false;
            }
            else
            {
                splListDetails.Panel2.Visible = true;
                txtDbName.Text = db.Name;
                cmbDSN.SelectedIndex = cmbDSN.FindStringExact(db.DSN);
                txtUsername.Text = db.Username;
                txtPassword.Text = db.Password;
                chkAutoCommit.Checked = db.AutoCommit;
                _dbModified = false;
                btnSaveChanges.Visible = false;
            }
        }

        private bool ConfirmChange()
        {
            if (_currentDb != null && _dbModified)
            {
                string name = _currentDb.Name;
                if (!App.Config.Databases.Contains(_currentDb))
                    name = txtDbName.Text;
                DialogResult dr = MessageBox.Show("Do you want to save the changes made to " + name + " ?",
                                                    "Save changes ?",
                                                    MessageBoxButtons.YesNoCancel,
                                                    MessageBoxIcon.Question);
                if (dr == DialogResult.Cancel)
                {
                    return false;
                }
                else if (dr == DialogResult.Yes)
                {
                    SaveDbProperties();
                }
            }
            return true;
        }

        private void DbPropertyChanged(object sender, EventArgs e)
        {
            _dbModified = true;
            btnSaveChanges.Visible = true;
        }

        private void SaveDbProperties()
        {
            _currentDb.Name = txtDbName.Text;
            _currentDb.DSN = cmbDSN.SelectedItem as string;
            _currentDb.Username = txtUsername.Text;
            _currentDb.Password = txtPassword.Text;
            _currentDb.AutoCommit = chkAutoCommit.Checked;
            _dbModified = false;
            if (!App.Config.Databases.Contains(_currentDb))
            {
                App.Config.Databases.Add(_currentDb);
            }
            dbBindingSource.ResetBindings(false);
            lstDatabases.SelectedIndex = App.Config.Databases.IndexOf(_currentDb);
            btnSaveChanges.Visible = false;
            _listModified = true;
        }

        private void btnSaveChanges_Click(object sender, EventArgs e)
        {
            if (_currentDb != null)
            {
                SaveDbProperties();
            }
        }

        private void btnNewDatabase_Click(object sender, EventArgs e)
        {
            if (!ConfirmChange())
            {
                return;
            }
            
            lstDatabases.SelectedIndex = -1;
            _currentDb = new Database();
            _currentDb.Name = "New database";
            splListDetails.Panel2.Visible = true;
            txtDbName.Text = _currentDb.Name;
            cmbDSN.SelectedIndex = -1;
            txtUsername.Clear();
            txtPassword.Clear();
            chkAutoCommit.Checked = false;
            _dbModified = false;
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            if (_currentDb == null)
            {
                this.DialogResult = DialogResult.None;
            }
        }

        private void lstDatabases_DoubleClick(object sender, EventArgs e)
        {
            if (lstDatabases.SelectedItem != null)
            {
                _currentDb = lstDatabases.SelectedItem as Database;
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        private void ConnectionDialog_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (_listModified && this.DialogResult == DialogResult.OK)
                App.SaveConfig();
            _listModified = false;
        }

        private void btnDeleteDatabase_Click(object sender, EventArgs e)
        {
            if (lstDatabases.SelectedItem != null)
            {
                App.Config.Databases.Remove(lstDatabases.SelectedItem as Database);
                _currentDb = null;
                _listModified = true;
                splListDetails.Panel2.Visible = false;
                dbBindingSource.ResetBindings(false);
            }
        }
    }
}